package com.sansecy.customview.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import com.sansecy.customview.R;
import com.sansecy.customview.util.DisplayUtils;

public class CircleRingView extends View {

    /**
     * 断食日可吃限额
     */
    private int FAST_CALORIES = 800;
    private int mWidth;
    private int mHeight;

    private int mArcLeft;
    private Paint mRingPaint;
    private Paint mPointPaint;
    private int mPointAngle;
    private int mSwipeAngle = 45;
    private Paint mShadowPaint;

    private int startColor = 0xFFFF8F00;
    private int centerColor = 0xFFF6DA9D;
    private int endColor = 0xFFFF8F00;

    private int overStartColor = 0xFFFEE140;
    private int overCenterColor = 0xFFFF8F00;
    private int overEndColor = 0xFFFA709A;

    private Context mContext;

    /**
     * 圆点外圈色值
     */
    private int nodeOutlineColor = 0xFFFDEFD6;
    /**
     * 圆点中心点色值
     */
    private int nodeCenterColor = 0xFFFEFAF2;


    private float innerCircleRadius;

    private int size35DP;
    private int size48DP;
    private int size3DP;
    private int size14DP = DisplayUtils.dp2px(14);

    private boolean isFastDay = false;

    private SweepGradient sweepGradient;
    private SweepGradient overGradient;
    private int[] overColors = {overStartColor, overCenterColor, overEndColor};
    private int[] colors = {startColor, centerColor, endColor};
    private int[] nodeColors = {nodeCenterColor, nodeOutlineColor, nodeCenterColor};
    private float[] positions = {0f, 0.5f, 1f};
    private float[] radialGradientPositions = {0f, 0.93f, 1.0f};
    private Rect mQuestionSrcRect = new Rect();
    private Rect mQuestionDstRect = new Rect();

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mSwipeAngle == mPointAngle) {
                mHandler.removeMessages(0);
            } else {
                ++mSwipeAngle;
                postInvalidate();
            }
        }
    };
    private boolean mShowQuestion;
    private Bitmap mQuestionImage;
    private int mTouchSlop;


    // TODO 使用动画代替Handler的方式
    private void startAnimation() {

    }

    private boolean mShowZero = true;
    private boolean mIsVisitor;

    private Paint mSwipePaint;
    private Paint mTextPaint;
    private int dp14 = DisplayUtils.dp2px(14);

    public CircleRingView(Context context) {
        this(context, null);
    }

    public CircleRingView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleRingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
        initParams(context);
    }

    private void initParams(Context context) {

        // 还可以吃多少卡路里的数字颜色
        int canEatCaloriesColor = 0xFFFB848B;

        //"还可以吃"文字颜色
        int canEatCaloriesTipsColor = 0xFF666666;
        this.mContext = context;
        mIsVisitor = false;
        size35DP = DisplayUtils.dp2px(35);
        size48DP = DisplayUtils.dp2px(55);
        size3DP = DisplayUtils.dp2px(3);
        // 处理渐变色相关代码
        sweepGradient = new SweepGradient(mWidth / 2.0f, mHeight / 2.0f, colors, positions);
        overGradient = new SweepGradient(mWidth / 2.0f, mHeight / 2.0f, overColors, positions);
        innerCircleRadius = DisplayUtils.dp2px(8.5f);
        // 阴影色值
        int shadowColor = 0x18FB7F8E;
        int ringWidth = 14;
        // 阴影
        mShadowPaint = new Paint();
        mShadowPaint.setStrokeWidth(DisplayUtils.dp2px(ringWidth + 5));
        mShadowPaint.setAntiAlias(true);
        mShadowPaint.setStyle(Paint.Style.STROKE);
        mShadowPaint.setStrokeCap(Paint.Cap.ROUND);
        mShadowPaint.setColor(shadowColor);
        //圆弧Paint
        mRingPaint = new Paint();
        mRingPaint.setStrokeWidth(dp14);
        mRingPaint.setAntiAlias(true);
        mRingPaint.setStyle(Paint.Style.STROKE);
        mRingPaint.setStrokeCap(Paint.Cap.ROUND);
        mRingPaint.setColor(ContextCompat.getColor(context, R.color.diet_home_circle_bg));
        //圆弧上的圆的Paint
        mPointPaint = new Paint();
        mPointPaint.setStrokeWidth(DisplayUtils.dp2px(1));
        mPointPaint.setAntiAlias(true);
        mPointPaint.setStyle(Paint.Style.FILL);
        //进度条Paint
        mSwipePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mSwipePaint.setStrokeWidth(DisplayUtils.dp2px(ringWidth));
        mSwipePaint.setAntiAlias(true);
        mSwipePaint.setStyle(Paint.Style.STROKE);
        mSwipePaint.setStrokeCap(Paint.Cap.ROUND);

        mSwipePaint.setColor(ContextCompat.getColor(context, R.color.diet_home_circle_bg));

        //进度值Paint
        mTextPaint = new Paint();
        mTextPaint.setStrokeWidth(DisplayUtils.dp2px(1));
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize(DisplayUtils.sp2px(55));
        Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/BebasNeueBold.ttf");
        mTextPaint.setTypeface(typeface);

        // 还可以吃多少的数字专用画笔
        canEatPaint = new Paint();
        canEatPaint.setStrokeWidth(DisplayUtils.dp2px(1));
        canEatPaint.setAntiAlias(true);
        canEatPaint.setStyle(Paint.Style.FILL);
        canEatPaint.setTextSize(DisplayUtils.sp2px(12));
        canEatPaint.setColor(canEatCaloriesColor);

        // 还可以吃多少的文字专用画笔
        testPaint = new Paint();
        testPaint.setStrokeWidth(DisplayUtils.dp2px(1));
        testPaint.setAntiAlias(true);
        testPaint.setStyle(Paint.Style.FILL);
        testPaint.setTextSize(DisplayUtils.sp2px(12));
        testPaint.setColor(canEatCaloriesTipsColor);

        //百分号Paint
        Paint mPercentPaint = new Paint();
        mPercentPaint.setStrokeWidth(DisplayUtils.dp2px(1));
        mPercentPaint.setAntiAlias(true);
        mPercentPaint.setStyle(Paint.Style.FILL);
        mPercentPaint.setTextSize(DisplayUtils.sp2px(25));
        //Rectf所需要
        mArcLeft = dp14 / 2;
    }

    RectF rectF = new RectF();

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = mWidth;
        int height = mHeight;

        rectF.left = mArcLeft;
        rectF.top = mArcLeft;
        rectF.right = height - mArcLeft;
        rectF.bottom = width - mArcLeft;
        // 不做旋转
        canvas.rotate(90, width / 2.0f, height / 2.0f);
        //正常圆弧
        canvas.drawArc(rectF, 45, 270, false, mRingPaint);
        if (mPointAngle >= 0 && mPointAngle <= 45) {
            mSwipeAngle = 45;
            mPointAngle = 45;
        } else if (mPointAngle > 315 & mPointAngle <= 360) {
            mSwipeAngle = 315;
            mPointAngle = 315;
        }

        float mCircleX = width / 2.0f;
        float mCircleY = height / 2.0f;
        if (mSwipeAngle <= mPointAngle) {
            float radius = (float) ((width - mArcLeft - mArcLeft) / 2);
            float pointX = (float) (mCircleX + radius * Math.cos(mSwipeAngle * 3.14 / 180));
            float pointY = (float) (mCircleY + radius * Math.sin(mSwipeAngle * 3.14 / 180));
            if (isOver) {
                //进度圆弧，模仿进度条
                mSwipePaint.setShader(overGradient);
            } else {
                //进度圆弧，模仿进度条
                mSwipePaint.setShader(sweepGradient);
            }

            canvas.drawArc(rectF, 45, mSwipeAngle - 45, false, mShadowPaint);
            canvas.drawArc(rectF, 45, mSwipeAngle - 45, false, mSwipePaint);
            RadialGradient radialGradient = new RadialGradient(pointX, pointY, innerCircleRadius, nodeColors, radialGradientPositions, Shader.TileMode.CLAMP);
            mPointPaint.setShader(radialGradient);
            //圆弧上的圆
            canvas.drawCircle(pointX, pointY, innerCircleRadius, mPointPaint);

//            float realX;
//            float realY;
//            float markX = (float) (mCircleX + radius * Math.cos(markAngle * 3.14 / 180));
//            float markY = (float) (mCircleY + radius * Math.sin(markAngle * 3.14 / 180));
            if (mIsVisitor) {
                return;
            }

//            if (mode == MARK_LEFT) {
//                realX = markX - fastWidth;
//                realY = markY;
//            } else {
//                realX = markX - fastWidth;
//                realY = markY - fastHeight;
//            }
//            if (isFastDay) {
//                canvas.drawBitmap(fastIcon, realX, realY, new Paint());
//            }

            canvas.rotate(-90, width / 2.0f, height / 2.0f);
            //测量文本宽度
            float v = mTextPaint.measureText(String.valueOf(alreadyEatCalories));
            //绘制文本
            if (mShowZero || alreadyEatCalories != 0) {
                canvas.drawText("" + alreadyEatCalories, mCircleX - (int) v / 2.0f, mCircleY, mTextPaint);
            }

            float tipTextY = mCircleY + size35DP;
            if (canEatCalories == 0) {
                // 测量还可以吃消耗卡路里文字的宽度
                float canEatCaloriesWidth = testPaint.measureText(tips);
                // "还可以吃"或者"吃多了"
                canvas.drawText(tips, mCircleX - (int) canEatCaloriesWidth / 2.0f, tipTextY, testPaint);
            } else {
                // 测量还可以吃消耗卡路里文字的宽度
                String kcalText = canEatCalories + "kcal";
                float canEatCaloriesWidth = testPaint.measureText(tips + kcalText);
                float kcalTextWidth = testPaint.measureText(kcalText);
                float tipX = mCircleX - (int) canEatCaloriesWidth / 2.0f;
                // "还可以吃"或者"吃多了"
                canvas.drawText(tips, tipX, tipTextY, testPaint);
                float onlyTipsWidth = canEatPaint.measureText(tips);
                // 还可以吃数字部分
                float questionLeft = tipX + onlyTipsWidth + size3DP;

                canvas.drawText(kcalText, questionLeft, tipTextY, canEatPaint);
                if (mQuestionImage != null && mShowQuestion) {
                    mQuestionDstRect.set((int) (questionLeft + kcalTextWidth + size3DP), (int) (tipTextY - size14DP), (int) (questionLeft + size14DP + kcalTextWidth + size3DP), (int) tipTextY);
                    canvas.drawBitmap(mQuestionImage, mQuestionSrcRect, mQuestionDstRect, null);
                }
            }

            if (isFastDay) {
                // 测量"断食日"文字宽度
                float fastWidth = testPaint.measureText("断食日");
                canvas.drawText("断食日", mCircleX - (int) fastWidth / 2.0f, mCircleY + size48DP, testPaint);
            }

            mHandler.sendEmptyMessageDelayed(0, 10);
        }

    }

    private int downX;
    private int downY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                downX = x;
                downY = y;
                if (mShowQuestion && mQuestionDstRect.contains(downX, downY)) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                int a = Math.abs(x - downX);
                int b = Math.abs(y - downY);
                double sqrt = Math.sqrt(a * a + b * b);
                //放下和抬起的位置距离少于滑动阈值，为点击
                if (sqrt < mTouchSlop) {
                    if (mShowQuestion && mOnQuestionClickListener != null) {
                        mOnQuestionClickListener.onClick();
                        return true;
                    } else {
                        performClick();
                        return true;
                    }
                }
                break;
        }
        return super.onTouchEvent(event);

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

    private static final String TAG = "CircleRingView-App";
    private long alreadyEatCalories;
    private String tips = "";
    private long canEatCalories;
    private Paint canEatPaint;
    private Paint testPaint;
    //    private Bitmap fastIcon; // 断食结点小图标
//    private int mode = MARK_LEFT; // 断食图标方向
//    private int fastWidth;  // 断食宽度
//    private int fastHeight; // 断食高度
    private boolean isOver = false;

    public void setData(long total, long current, boolean isFastDay, boolean showZero, long base) {
        mShowZero = showZero;
        this.setData(total, current, isFastDay, base);
    }

    /**
     * 设置卡路里消耗情况
     *
     * @param total   总的可以吃的卡路里
     * @param current 当前吃的卡路里
     */
    public void setData(long total, long current, boolean isFastDay, long base) {
        this.isFastDay = isFastDay;
        if (isFastDay) {
            this.FAST_CALORIES = (int) base;
        }
        alreadyEatCalories = current;
        mSwipeAngle = 45;
        if (isFastDay) {
            total = FAST_CALORIES;
        }
        if (current > total) {
            isOver = true;
            tips = mContext.getString(R.string.diet_home_data_tips_over);
            mPointAngle = 360;
            canEatCalories = current - total;
        } else if (current < total) {
            isOver = false;
            tips = mContext.getString(R.string.diet_home_data_tips);
            mPointAngle = (int) ((current * 1.0f / total) * 270) + 45;
            canEatCalories = total - current;
        } else {
            isOver = false;
            tips = mContext.getString(R.string.diet_home_data_just_ok);
            mPointAngle = (int) ((current * 1.0f / total) * 270) + 45;
            canEatCalories = total - current;
        }

        if (isFastDay) {
            if (current > FAST_CALORIES) {
                tips = mContext.getString(R.string.diet_home_data_tips_over);
                canEatCalories = current - FAST_CALORIES;
            } else if (current < FAST_CALORIES) {
                tips = mContext.getString(R.string.diet_home_data_tips);
                canEatCalories = FAST_CALORIES - current;
            } else {
                tips = mContext.getString(R.string.diet_home_data_just_ok);
                canEatCalories = FAST_CALORIES - current;
            }
        }
        mHandler.sendEmptyMessageDelayed(0, 5);
    }

    //停止绘制View
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mHandler.removeMessages(0);
    }

    public void isShowQuestion(boolean showQuestion, @DrawableRes int imageResource) {
        mShowQuestion = showQuestion;
        if (showQuestion) {
            mQuestionImage = BitmapFactory.decodeResource(getResources(), imageResource);
            mQuestionSrcRect.set(0, 0, mQuestionImage.getWidth(), mQuestionImage.getHeight());
        }
        invalidate();
    }

    private OnQuestionClickListener mOnQuestionClickListener;

    public void setOnQuestionClickListener(OnQuestionClickListener onQuestionClickListener) {
        mOnQuestionClickListener = onQuestionClickListener;
    }

    public interface OnQuestionClickListener {
        void onClick();
    }

}